package com.project.server.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.project.server.dto.DashboardDataDTO;
import com.project.server.entity.SysUser;
import com.project.server.mapper.*;
import com.project.server.service.DashboardService;
import com.project.server.service.SysUserService;
import com.project.server.service.ConsultationService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

@Service
@RequiredArgsConstructor
public class DashboardServiceImpl implements DashboardService {


    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private ConsultationService consultationService;

    @Override
    public DashboardDataDTO getDashboardData(String timeRange) {
        DashboardDataDTO dto = new DashboardDataDTO();

        // 获取基础统计数据
        setBasicStatistics(dto);

        // 获取用户趋势数据
        setUserTrend(dto, timeRange);

        // 获取性别分布
        setGenderDistribution(dto);

        // 获取角色分布
        setRoleDistribution(dto);

        return dto;
    }

    private void setBasicStatistics(DashboardDataDTO dto) {
        // 总用户数
        Long totalUsers = sysUserService.count();
        dto.setTotalUsers(totalUsers);

        // 医生数量
        Long doctorCount = sysUserService.count(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getRoleId, 2));
        dto.setTotalDoctors(doctorCount);

        // 计算用户增长率
        LocalDateTime lastMonth = LocalDateTime.now().minusMonths(1);
        Long lastMonthUsers = sysUserService.count(new LambdaQueryWrapper<SysUser>()
                .le(SysUser::getCreateTime, lastMonth));

        if (lastMonthUsers > 0) {
            double growth = ((double)(totalUsers - lastMonthUsers) / lastMonthUsers) * 100;
            dto.setUserGrowth(Math.round(growth * 10.0) / 10.0);
        } else {
            dto.setUserGrowth(0.0);
        }

        // 今日活跃用户（示例：今日创建的用户）
        LocalDateTime todayStart = LocalDate.now().atStartOfDay();
        Long activeUsers = sysUserService.count(new LambdaQueryWrapper<SysUser>()
                .ge(SysUser::getCreateTime, todayStart));
        dto.setActiveUsers(activeUsers);

        // 系统消息数（示例数据）
//        dto.setTotalMessages(15L);

        // 获取问诊总量
        Long consultationCount = consultationService.count();
        dto.setConsultationCount(consultationCount);
    }

    private void setUserTrend(DashboardDataDTO dto, String timeRange) {
        List<String> dates = new ArrayList<>();
        List<Long> data = new ArrayList<>();
        DateTimeFormatter formatter;
        LocalDateTime startTime;

        switch (timeRange) {
            case "week":
                formatter = DateTimeFormatter.ofPattern("MM-dd");
                startTime = LocalDateTime.now().minusDays(6);
                for (Long i = 0L; i < 7; i++) {
                    LocalDateTime day = startTime.plusDays(i);
                    dates.add(day.format(formatter));
                    Long count = sysUserService.count(new LambdaQueryWrapper<SysUser>()
                            .ge(SysUser::getCreateTime, day)
                            .lt(SysUser::getCreateTime, day.plusDays(1)));
                    data.add(count);
                }
                break;

            case "month":
                formatter = DateTimeFormatter.ofPattern("MM-dd");
                startTime = LocalDateTime.now().minusDays(29);
                for (Long i = 0L; i < 30; i++) {
                    LocalDateTime day = startTime.plusDays(i);
                    dates.add(day.format(formatter));
                    Long count = sysUserService.count(new LambdaQueryWrapper<SysUser>()
                            .ge(SysUser::getCreateTime, day)
                            .lt(SysUser::getCreateTime, day.plusDays(1)));
                    data.add(count);
                }
                break;

            case "year":
                formatter = DateTimeFormatter.ofPattern("yyyy-MM");
                startTime = LocalDateTime.now().minusMonths(11);
                for (Long i = 0L; i < 12; i++) {
                    LocalDateTime month = startTime.plusMonths(i);
                    dates.add(month.format(formatter));
                    Long count = sysUserService.count(new LambdaQueryWrapper<SysUser>()
                            .ge(SysUser::getCreateTime, month)
                            .lt(SysUser::getCreateTime, month.plusMonths(1)));
                    data.add(count);
                }
                break;
        }

        dto.setTrendDates(dates);
        dto.setTrendData(data);
    }

    private void setGenderDistribution(DashboardDataDTO dto) {
        Long maleCount = sysUserService.count(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getGender, 1));
        Long femaleCount = sysUserService.count(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getGender, 2));

        dto.setMaleCount(maleCount);
        dto.setFemaleCount(femaleCount);
    }

    private void setRoleDistribution(DashboardDataDTO dto) {
        dto.setAdminCount(sysUserService.count(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getRoleId, 1)));
        dto.setDoctorCount(sysUserService.count(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getRoleId, 2)));
        dto.setNormalUserCount(sysUserService.count(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getRoleId, 3)));
    }


    /**
     * 计算环比增长率
     */
    private double calculateTrend(long current, long previous) {
        if (previous == 0) return 0;
        return BigDecimal.valueOf((current - previous) * 100.0 / previous)
                .setScale(1, RoundingMode.HALF_UP)
                .doubleValue();
    }
}
